package com.cjkj.applet.service.impl;

import com.cjkj.applet.domain.*;
import com.cjkj.applet.domain.dto.EquipmentDto;
import com.cjkj.applet.domain.dto.HospitalEquipmentDto;
import com.cjkj.applet.mapper.*;
import com.cjkj.applet.service.IAppletBindInfoService;
import com.cjkj.common.core.constant.EquipmentConstants;
import com.cjkj.common.core.exception.ServiceException;
import com.cjkj.common.core.utils.DateUtils;
import com.cjkj.common.core.utils.StringUtils;
import com.cjkj.common.core.web.domain.AjaxResult;
import com.cjkj.common.security.utils.SecurityUtils;
import com.cjkj.system.api.domain.THospitalUser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 小程序端账号绑定设备情况Service业务层处理
 * 
 * @author cjkj
 * @date 2024-08-30
 */
@Service
public class AppletBindInfoServiceImpl implements IAppletBindInfoService 
{
    @Resource
    private AppletAccountMapper appletAccountMapper;

    @Resource
    private AppletBindInfoMapper appletBindInfoMapper;

    @Resource
    private THospitalUserMapper hospitalUserMapper;

    @Resource
    private THospitalEquipmentMapper hospitalEquipmentMapper;

    @Resource
    private TEquipmentUsageRecordsMapper equipmentUsageRecordsMapper;

    @Resource
    private TPatVisitMapper patVisitMapper;

    @Override
    public void add(EquipmentDto equipment) {

        // 当前账号ID
        Long appUserId = SecurityUtils.getAppUserId();
        String appOpenId = SecurityUtils.getAppOpenId();
        // 设备编号
        String equipmentNo = equipment.getEquipmentNo();
        // 设备类型
        String equipmentType = equipment.getEquipmentType();

        // 1、判断当前账号绑定的医生
        AppletAccount appletAccount = appletAccountMapper.selectAppletAccountByOpenId(appOpenId);
        if(appletAccount == null) {
            throw new ServiceException("账号不存在！");
        }
        String doctor = appletAccount.getDoctor();
        THospitalUser hospitalUser = hospitalUserMapper.selectTHospitalUserByUserName(doctor);
        if(hospitalUser == null){
            throw new ServiceException("医生账号不存在！");
        }

        // 2、判断设备号是否存在
        HospitalEquipmentDto query = new HospitalEquipmentDto();
        query.setHospitalId(hospitalUser.getHospitalId());
        query.setDeptId(hospitalUser.getDeptId());
        query.setEquipmentNo(equipmentNo);
        query.setEquipmentType(equipmentType);
        THospitalEquipment hospitalEquipment = hospitalEquipmentMapper.select(query);
        if(hospitalEquipment == null){
            throw new ServiceException("设备不存在！");
        }

        // 3、判断当前用户是否绑定了该设备
        AppletBindInfo info = appletBindInfoMapper.select(equipmentNo, appUserId);
        if(info != null) {
            throw new ServiceException("您已绑定该设备！");
        }

        // 4、添加绑定信息
        AppletBindInfo bindInfo = new AppletBindInfo();
        bindInfo.setAccountId(appUserId);
        bindInfo.setEquipmentNo(equipmentNo);
        bindInfo.setEquipmentType(equipmentType);
        bindInfo.setStartTime(DateUtils.getNowDate());
        appletBindInfoMapper.insertAppletBindInfo(bindInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unbind(List<String> equipmentNos) {
        // 当前账号ID
        Long appUserId = SecurityUtils.getAppUserId();
        // 当前时间
        Date now = DateUtils.getNowDate();

        for (String equipmentNo : equipmentNos) {
            AppletBindInfo bindInfo = new AppletBindInfo();
            bindInfo.setAccountId(appUserId);
            bindInfo.setEquipmentNo(equipmentNo);
            bindInfo.setEndTime(now);
            appletBindInfoMapper.updateByAccountIdAndEquipmentNo(bindInfo);
        }
    }

    @Override
    public List<String> getList(String dataType) {
        // 当前账号ID
        Long appUserId = SecurityUtils.getAppUserId();
        return appletBindInfoMapper.selectBindEquipmentNos(appUserId, dataType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult receive(List<String> equipmentNos) {
        if (equipmentNos == null || equipmentNos.isEmpty()) {
            throw new ServiceException("设备编号不能为空！");
        }

        // 当前账号信息（接收方）
        Long appUserId = SecurityUtils.getAppUserId();
        AppletAccount account = appletAccountMapper.selectAppletAccountByAccountId(appUserId);
        String doctor = account == null || account.getDoctor() == null ? "" : account.getDoctor();
        // 当前时间
        Date now = DateUtils.getNowDate();

        AppletAccount transferAccount = null;
        for (String equipmentNo : equipmentNos) {
            // 1、将参数中的设备号设置为绑定结束
            AppletBindInfo bindInfo = appletBindInfoMapper.selectByEquipmentNo(equipmentNo);
            if(bindInfo != null) {
                // 移交方信息
                Long transferAccountId = bindInfo.getAccountId();
                if(appUserId.longValue() == transferAccountId.longValue()) {
                    throw new ServiceException("自己不能跟自己交接！");
                }
                transferAccount = appletAccountMapper.selectAppletAccountByAccountId(transferAccountId);
                // 判断移交方的医生账号是否和接收方的医生账号一致，如果不一致不能交接
                if(transferAccount != null
                        && (transferAccount.getDoctor() == null || doctor.isEmpty() || doctor.equals(transferAccount.getDoctor()))
                ) {
                    bindInfo.setEndTime(now);
                    bindInfo.setBindFlag("1");
                    appletBindInfoMapper.updateAppletBindInfo(bindInfo);
                } else {
                    throw new ServiceException("双方绑定的医生账号不一致，无法进行交接！");
                }
            }

            // 2、将参数中的设备号绑定到当前微信账号下
            AppletBindInfo newBind = new AppletBindInfo(null, appUserId,
                    EquipmentConstants.EQUIPMENT_TYPE_MONITOR_PAD_TYPE, equipmentNo, now, null, "0");
            appletBindInfoMapper.insertAppletBindInfo(newBind);

            // 3、如果设备开了单绑定了患者，则把患者也转入当前微信账号下
            // 3-1 查询该设备是否在使用
            TEquipmentUsageRecords usageRecords = equipmentUsageRecordsMapper.selectInUseByEquipmentNo(equipmentNo, EquipmentConstants.EQUIPMENT_USE_FLAG_INUSE);
            if(usageRecords != null) {
                // 3-2 查询正在使用该设备的患者是否通过小程序开单
                Long visitNo = usageRecords.getVisitNo();
                TPatVisit tPatVisit = patVisitMapper.selectTPatVisitByVisitNo(visitNo);
                if(tPatVisit != null && tPatVisit.getAppletAccountId() != null) {
                    // 把该患者转至当前账号下
                    TPatVisit updateInfo = new TPatVisit();
                    updateInfo.setVisitNo(visitNo);
                    updateInfo.setAppletAccountId(appUserId);
                    patVisitMapper.updateTPatVisit(updateInfo);
                }
            }
        }

        if (transferAccount != null) {
            // 4、接收方医生账号绑定为移交方医生
            if(StringUtils.isBlank(doctor) && StringUtils.isNotBlank(transferAccount.getDoctor())) {
                doctor = transferAccount.getDoctor();
                account = new AppletAccount();
                account.setAccountId(appUserId);
                account.setDoctor(doctor);
                appletAccountMapper.updateAppletAccount(account);
            }

            // 5、移交方如果把所有设备和患者移交完毕了，解绑掉医生账号
            Long transferAccountId = transferAccount.getAccountId();
            int count = appletBindInfoMapper.selectBindCountByAppUserId(transferAccountId);
            if(count <= 0) {
                // 5.1、如果还有未操作出院的患者一并移交
                int patVisitCount = patVisitMapper.selectCountByAppUserId(transferAccountId);
                if(patVisitCount >= 0) {
                    patVisitMapper.patientReceive(transferAccountId, appUserId);
                }
                // 5.2、解绑医生账号
                transferAccount.setDoctor(null);
                appletAccountMapper.setDoctorNull(transferAccountId);
            }
        }
        return AjaxResult.success("交接成功！", doctor);
    }
}
